package com.scpii.api.common.auth.token;

import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;

import com.scpii.api.common.auth.AuthorizationRequest;
import com.scpii.api.common.auth.ClientAuthentication;
import com.scpii.api.common.auth.client.ClientDetailsService;
import com.scpii.api.common.exception.InvalidRequestException;
import com.scpii.api.common.exception.InvalidUserException;

public class ResourceOwnerPasswordTokenGranter extends AbstractTokenGranter {

	public static final String GRANT_TYPE = "password";

	private final AuthenticationManager authenticationManager;

	public ResourceOwnerPasswordTokenGranter(
			AuthenticationManager authenticationManager,
			AuthorizationServerTokenServices tokenServices,
			ClientDetailsService clientDetailsService) {
		super(tokenServices, clientDetailsService, GRANT_TYPE);
		this.authenticationManager = authenticationManager;
	}

	@Override
	protected ClientAuthentication getClientAuthentication(
			AuthorizationRequest clientToken) {

		Map<String, String> parameters = clientToken
				.getAuthorizationParameters();
		String username = parameters.get("username");
		String password = parameters.get("password");
		if (StringUtils.isBlank(username)) {
			throw new InvalidRequestException("username must be provider ");
		}

		if (StringUtils.isBlank(password)) {
			throw new InvalidRequestException("password must be provider ");
		}
		Authentication userAuth = new UsernamePasswordAuthenticationToken(
				username, password);
		try {
			userAuth = authenticationManager.authenticate(userAuth);
		} catch (BadCredentialsException e) {
			throw new InvalidUserException(e.getMessage());
		}
		if (userAuth == null || !userAuth.isAuthenticated()) {
			throw new InvalidUserException("Could not authenticate user: "
					+ username);
		}

		return new ClientAuthentication(clientToken, userAuth);

	}

}
